package com.zkzx.wlhy.adaptor.config.feign;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.zkzx.wlhy.adaptor.util.RSA;
import feign.*;
import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author young Email:yanghui@zkraising.com
 * @description
 * @company 北京中科智兴物联科技有限公司 @版权所有
 * @since 2021年05月18日 10时46分
 */
@Slf4j
@Configuration
public class FeignConfiguration {

    private static final String DATA = "data";

    private final static  String POST = "POST";

    private final static  String GET = "GET";



    @Bean
    public RequestInterceptor requestTokenInterceptor() {
        return requestTemplate -> {
            requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

            JSONObject date = new JSONObject();
                // 封装信息 怎么请求
                try {
                    Map<String, Collection<String>> params = requestTemplate.queries();
                    Map<String, Collection<String>> newParams = new HashMap<>();
                    String method = requestTemplate.method();
                    if(GET.equals(method)){
                        params.forEach((s, strings) -> {
                            String decode = null;
                            try {
                                decode = URLDecoder.decode(strings.stream().findFirst().get(), Util.UTF_8.name());
                            } catch (UnsupportedEncodingException e) {
                                log.error("解析参数异常：",e);
                            }
                            date.put(s, RSA.encrypt(decode));
                            List<String> strs = new ArrayList<>();
                            strs.add(RSA.encrypt(decode));
                            newParams.put(s,strs);
                        });
                        requestTemplate.queries(null);
                        requestTemplate.queries(newParams);
                    }


                    if(POST.equals(method)) {
                        String value = requestTemplate.requestBody().asString();
                        log.info("调用网货入参信息：{}",value);
                        requestTemplate
                                .body(Request.Body.encoded(value.getBytes(), Util.UTF_8));
                    }
                } catch (Exception e) {
                    log.error("getSign error：", e);
                }
        };
    }

    @Bean
    public Decoder feignDecoder() {
        HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new ResultStatusDecoder(new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(objectFactory))));
    }

    private static ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE);
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return objectMapper;
    }

    @Bean
    public Retryer retryer(){
        return new Retryer.Default();
    }


    /**
     * feign返回值拦截
     * @author liufei
     */
    private class ResultStatusDecoder implements Decoder {

        final Decoder delegate;

        public ResultStatusDecoder(Decoder delegate) {
            Objects.requireNonNull(delegate, "Decoder must not be null. ");
            this.delegate = delegate;
        }

        @Override
        public Object decode(Response response, Type type) throws IOException {
            // 判断是否返回参数是否是异常
            String resultStr = IOUtils.toString(response.body().asInputStream(), StandardCharsets.UTF_8.name());
            log.info("网货返回信息：{}",resultStr);
            // 拿到返回值，进行自定义逻辑处理
            JSONObject jsonObject = JSONObject.parseObject(resultStr);
//            String encryptedData  = jsonObject.getString(DATA);
//            if (StringUtils.hasText(sencryptedData)){
//                try {
//                    String decryptString = null;// RSA.decryptByPrivateKey(encryptedData).toString(); 返回参数信息是否需要解密
//                    JSONObject dataObject = JSONObject.parseObject(decryptString);
//                    jsonObject.put(DATA,dataObject);
//                } catch (Exception e) {
//                    log.error("解密报错" + e);
//                }
//            }
            // 回写body,因为response的流数据只能读一次，这里回写后重新生成response
            return delegate.decode(response.toBuilder().body(jsonObject.toString(), StandardCharsets.UTF_8).build(), type);
        }
    }
}
